package com.woniu108.valueAdded.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu108.carService.commons.log.AdminHistoryLog;
import com.woniu108.carService.commos.dto.SimpleTicketDto;
import com.woniu108.carService.commos.dto.TicketDto;
import com.woniu108.carService.commos.dto.UserInfoDto;
import com.woniu108.carService.commos.dto.UserTicketDto;
import com.woniu108.carService.commos.exception.WoniuException;
import com.woniu108.carService.commos.model.Result;
import com.woniu108.carService.commos.util.JWTUtil;
import com.woniu108.carService.commos.util.RedisUtil;
import com.woniu108.carService.commos.util.StaticData;
import com.woniu108.valueAdded.client.PersonClient;
import com.woniu108.valueAdded.form.AddTicketForm;
import com.woniu108.valueAdded.form.AddTicketInfoForm;
import com.woniu108.valueAdded.form.AddTicketToUserForm;
import com.woniu108.valueAdded.form.TicketListForm;
import com.woniu108.valueAdded.model.Ticket;
import com.woniu108.valueAdded.param.AddTicketInfoParam;
import com.woniu108.valueAdded.param.AddTicketParam;
import com.woniu108.valueAdded.param.AddTicketToUserParam;
import com.woniu108.valueAdded.param.TicketListParam;
import com.woniu108.valueAdded.service.TicketService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 优惠券表 前端控制器
 * </p>
 *
 * @author yanxi
 * @since 2024-05-23
 */
@RestController
@RequestMapping("/ticket")
@Api(tags = "优惠券信息接口")
public class TicketController {


    @Resource
    private TicketService ticketService;
    @Resource
    private PersonClient personClient;
    @Resource
    private RedisUtil redisUtil;

    public String getAdminId(String token){
        String refreshToken=redisUtil.getString(token);
        String adminId= JWTUtil.parseAdminToken(refreshToken).get("adminId").toString();
        return adminId;
    }
    public String getUserId(String token){
        String refreshToken=redisUtil.getString(token);
        String userId=JWTUtil.parseUserToken(refreshToken).get("userId").toString();
        return userId;
    }

    public String getStoreAdminId(String token){
        String refreshToken=redisUtil.getString(token);
        String storeAdminId=JWTUtil.parseStoreAdminToken(refreshToken).get("storeAdminId").toString();
        return storeAdminId;
    }


    /**
     * 列表展示所有优惠券信息
     * @param form 优惠券列表筛选信息
     * @return Page<TicketDto> 选择的页码中展示的优惠券信息列表
     */
    @PostMapping("/ticketList.c")
    @ApiOperation("列表展示所有优惠券信息")
    public Result<Page<TicketDto>> ticketList(@RequestBody TicketListForm form){
        TicketListParam param=BeanUtil.toBean(form,TicketListParam.class);
        Page<TicketDto> dtos=ticketService.ticketList(param);
        return Result.newPageInstance(TicketDto.class).setData(dtos);
    }


    /**
     * 列表展示用户持有的所有优惠券信息
     * 同时检测所有优惠券信息是否过期,过期则删除该优惠券
     * @param userId 用户ID
     * @return List<UserTicketDto> 用户的优惠券详细信息集合(含持有数量)
     */
    @GetMapping("/userTickets")
    @ApiOperation("用户持有的所有优惠券信息")
    @ApiImplicitParam(name = "userId",value ="用户ID" )
    public Result<List<UserTicketDto>> userTickets(String userId){
        Result<UserInfoDto> result = personClient.getByUserId(userId);
        if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
        UserInfoDto userInfoDto = result.getData();
        String ticketDetails = userInfoDto.getTicketDetails();
        List<SimpleTicketDto> list = JSONUtil.toList(ticketDetails, SimpleTicketDto.class);
        List<UserTicketDto> dtos=new ArrayList<>();
        for (SimpleTicketDto ticket : list) {
            Ticket ticketInfo = ticketService.getById(ticket.getTicketId());
            //当发放时间+有效时间大于目前时间，表示这张优惠券未过期，加入更新集合
            if((ticket.getCreateTime().plusDays(ticketInfo.getLimitTime())).isAfter(LocalDateTime.now())){
                UserTicketDto dto = BeanUtil.toBean(ticketInfo, UserTicketDto.class);
                dto.setUserId(userId);
                dto.setCreateTime(ticket.getCreateTime());
                dto.setNumber(ticket.getNumber());
                dtos.add(dto);
            }
            //否则证明此优惠券已过期，不加入更新集合
        }
        return Result.newListInstance(UserTicketDto.class).setData(dtos);
    }


    /**
     * 查询用户使用的优惠卷信息（判定用户是否持有该优惠卷）
     * @param userId 用户ID
     * @param ticketId 优惠券种类ID
     * @return UserTicketDto 用户持有的对应种类优惠券信息(含持有数量)
     */
    @GetMapping("/checkUserTicketId")
    @ApiOperation("用户持有的单种优惠券信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId",value ="用户ID" ),
            @ApiImplicitParam(name = "ticketId",value ="优惠券种类ID" )
    })
    public Result<UserTicketDto> checkUserTicketId(String userId,Integer ticketId){
        Result<List<UserTicketDto>> result = this.userTickets(userId);
        if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
        List<UserTicketDto> dtos = result.getData();
        UserTicketDto dto1 = new UserTicketDto();
        for (UserTicketDto dto : dtos) {
            if(dto.getTicketId()==ticketId&&dto.getNumber()>0){
                dto1=dto;
            }
        }
        if(ObjectUtil.isEmpty(dto1)) throw new WoniuException("未持有该类型优惠券",10001);
        return Result.getResult(UserTicketDto.class).setData(dto1).setMsg("持有该优惠券");
    }

    /**
     * 消耗用户选择使用数量的优惠券
     * @param userId 用户ID
     * @param ticketId 优惠券种类ID
     * @param number 使用数量
     * @return result 接口是否正常访问结果
     */
    @GetMapping("/reduceUserTicket.api")
    @ApiOperation("消耗用户选择使用数量的优惠券")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId",value ="用户ID" ),
            @ApiImplicitParam(name = "ticketId",value ="优惠券种类ID" ),
            @ApiImplicitParam(name = "number",value ="使用数量" )
    })
    public Result reduceUserTicket(String userId,Integer ticketId,Integer number){
        Result<UserTicketDto> result = this.checkUserTicketId(userId, ticketId);
        if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
        UserTicketDto ticketDto = result.getData();
        Result<UserInfoDto> result1 = personClient.getByUserId(userId);
        if(result1.getCode()!=200) throw new WoniuException(result1.getMsg(),result1.getCode());
        UserInfoDto userInfoDto = result1.getData();
        String ticketDetails = userInfoDto.getTicketDetails();
        List<SimpleTicketDto> list = JSONUtil.toList(ticketDetails, SimpleTicketDto.class);
        List<SimpleTicketDto> list1 = new ArrayList<>();
        for (SimpleTicketDto dto : list) {
            if(dto.getTicketId()!=ticketId){
                list1.add(dto);
            }
            if(dto.getTicketId()==ticketId&&dto.getNumber()<number){
                throw new WoniuException("优惠券数量不足",10001);
            }
            if(dto.getTicketId()==ticketId&&dto.getNumber()>number){
                dto.setNumber(dto.getNumber()-number);
                list1.add(dto);
            }
            //当持有的优惠券与消耗的优惠券相等时，不添加到新details中
        }
        String jsonStr = JSONUtil.toJsonStr(list1);
        userInfoDto.setTicketDetails(jsonStr);
        Result result2 = personClient.updateTicketDetails(userId, jsonStr);
        if(result2.getCode()!=200) throw new WoniuException(result2.getMsg(),result2.getCode());
        return Result.getResult().setMsg("扣减用户优惠券成功");
    }

    /**
     * 新增优惠券
     * @param form 新增优惠券信息
     * @return result 接口是否正常访问结果
     */
    @PostMapping("/addTicket.api")
    @ApiOperation("新增优惠券信息")
    @AdminHistoryLog
    public Result addTicket(@RequestBody AddTicketForm form){
        AddTicketParam param=BeanUtil.toBean(form,AddTicketParam.class);
        Ticket ticket = BeanUtil.toBean(param, Ticket.class);
        ticket.setTicketType("通用");
        ticket.setTicketState(0);
        ticketService.save(ticket);
        return Result.getResult().setMsg("新增优惠券信息成功");
    }

    /**
     *向用户发放优惠券
     * @param form 发放优惠券信息（id,数量,发放对象)
     * @param token 获取adminId,用于记录管理员操作记录
     * @return result 是否正常完成接口
     */
    @PostMapping("/addTicketToUser.api")
    @ApiOperation("发放指定数量的优惠价给指定用户")
    @AdminHistoryLog
    public Result addTicketToUser(@RequestBody AddTicketToUserForm form,@RequestHeader String token){
        //获取用户原有优惠券信息
        AddTicketToUserParam param=BeanUtil.toBean(form,AddTicketToUserParam.class);
        Result<UserInfoDto> userInfoDtoResult = personClient.getByUserId(param.getUserId());
        if(userInfoDtoResult.getCode()!=200) throw new WoniuException(userInfoDtoResult.getMsg(),userInfoDtoResult.getCode());
        UserInfoDto userInfoDto = userInfoDtoResult.getData();
        System.out.println("userInfoDto:"+userInfoDto);
        String ticketDetails = userInfoDto.getTicketDetails();
        System.out.println("ticketDetails:"+ticketDetails);
        //将信息由JSON字符串转为list
        List<SimpleTicketDto> simpleTicketDtos = JSONUtil.toList(ticketDetails, SimpleTicketDto.class);
        System.out.println("simpleTicketDtos:"+simpleTicketDtos);
        //将新增优惠券信息加入list,重新转JSON字符串
        SimpleTicketDto simpleTicketDto = new SimpleTicketDto();
        simpleTicketDto.setTicketId(param.getTicketId());
        simpleTicketDto.setNumber(param.getNumber());
        simpleTicketDto.setCreateTime(LocalDateTime.now());
        simpleTicketDtos.add(simpleTicketDto);
        String newTicketDetails = JSONUtil.toJsonStr(simpleTicketDtos);
        //更新用户持有优惠券信息
        Result result = personClient.updateTicketDetails(param.getUserId(), newTicketDetails);
        if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
        return Result.getResult();
    }

    /**
     * 用户主动领取优惠券
     * @param token
     * @param ticketId 优惠券种类Id
     * @return result 是否正常完成接口功能
     */
    @GetMapping("/getTicket")
    @ApiOperation("用户领取指定优惠券(1张)")
    @ApiImplicitParam(name = "ticketId",value ="优惠券ID" )
    public Result getTicket(@RequestHeader String token,Integer ticketId){
        String userId = this.getUserId(token);
        if(userId==null) throw new WoniuException("非用户不可领取",10001);
        //获取用户原有优惠券信息
        Result<UserInfoDto> userInfoDtoResult = personClient.getByUserId(userId);
        if(userInfoDtoResult.getCode()!=200) throw new WoniuException(userInfoDtoResult.getMsg(),userInfoDtoResult.getCode());
        UserInfoDto userInfoDto = userInfoDtoResult.getData();
        String ticketDetails = userInfoDto.getTicketDetails();
        //将信息由JSON字符串转为list
        List<SimpleTicketDto> simpleTicketDtos = JSONUtil.toList(ticketDetails, SimpleTicketDto.class);
        //将新增优惠券信息加入list,重新转JSON字符串
        SimpleTicketDto simpleTicketDto = new SimpleTicketDto();
        simpleTicketDto.setTicketId(ticketId);
        simpleTicketDto.setNumber(1);
        simpleTicketDto.setCreateTime(LocalDateTime.now());
        simpleTicketDtos.add(simpleTicketDto);
        String newTicketDetails = JSONUtil.toJsonStr(simpleTicketDtos);
        //更新用户持有优惠券信息
        Result result = personClient.updateTicketDetails(userId, newTicketDetails);
        if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
        return Result.getResult();
    }

//    /**
//     * 修改优惠券信息
//     * @param form  修改优惠券信息
//     * @return result 是否正常完成接口功能
//     */
//    @PostMapping("/addTicketInfo.api")
//    @ApiOperation("修改优惠券种类")
//    public Result changeTicketInfo(@RequestBody AddTicketInfoForm form){
//        AddTicketInfoParam param = BeanUtil.toBean(form, AddTicketInfoParam.class);
//        Ticket ticket = BeanUtil.toBean(param, Ticket.class);
//        ticketService.updateById(ticket);
//        return Result.getResult().setMsg("新增优惠券种类成功");
//    }

    /**
     * 删除优惠券种类
     * @param ticketId
     * @return result 是否正常完成接口功能
     */
    @GetMapping("/deleteTicketInfo.api")
    @ApiImplicitParam(name = "ticketId",value ="优惠券ID" )
    @ApiOperation("删除优惠券种类")
    @AdminHistoryLog
    public Result deleteTicketInfo(Integer ticketId){
        Ticket ticket = ticketService.getById(ticketId);
        if(ObjectUtil.isEmpty(ticket)||ticket.getTicketState()!= StaticData.TICKET_STATE_NORMAL) throw new WoniuException("优惠券信息状态异常或不存在",10001);
        ticket.setTicketState(StaticData.TICKET_STATE_DELETE);
        ticketService.updateById(ticket);
        return Result.getResult().setMsg("删除优惠券种类成功");
    }


}

